import Define from "./common/Define";
import GameManager from "./manager/GameManager";
import Common from "./common/Common";
import LDataStone from "./datas/LDataStone";
import LDataStoneManager from "./datas/LDataStoneManager";
import LevelInfo from "./Levellnfo";
import ParticleEffectManager from "./manager/ParticleEffectManager";
import SoundManager from "./manager/SoundManager";
import UIManager from "./manager/UIManager";
import WXHelper from "./common/WXHelper";
import UserInfo from "./UserInfo";

// Learn TypeScript:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class Ball extends cc.Component {

    public rigidBody:cc.RigidBody;
    @property(cc.Label)
    labelNumber:cc.Label = null;

    @property(cc.Node)
    icon:cc.Node = null;
    
    @property(cc.Node)
    effectRoot:cc.Node = null;

    nTotalNumber:number = 0;
    
    isCanDrop:boolean = false;

    callBack:Function = null;

    physicsCircle:cc.PhysicsCircleCollider = null;

    stoneData:LDataStone = null;

    spriteIcon:cc.Sprite = null;

    initScore:number = null;
    isCanShake:boolean = true;

    private lastGravityScale:number = 0;
    private lastAngularVelocity:number = 0;
    private lasLlinearVelocity:cc.Vec2 = cc.Vec2.ZERO;

    private _stoneId: number = -1;
    public get stoneId(): number {
        return this._stoneId;
    }
    public set stoneId(value: number) {
        this._stoneId = value;
        this.stoneData = LDataStoneManager.GetDataById(value);
    }

    onLoad()
    { 
        this.rigidBody = this.node.getComponent<cc.RigidBody>(cc.RigidBody);
        this.rigidBody.active = false;
        this.rigidBody.linearVelocity = cc.Vec2.ZERO; 
        this.physicsCircle = this.node.getComponent<cc.PhysicsCircleCollider>(cc.PhysicsCircleCollider);
    }

    setNumber(total:number){
        this.nTotalNumber = total;
        this.initScore = this.nTotalNumber;
        this.labelNumber.string = Common.getShowNumber(this.nTotalNumber);
        this.icon.color = Common.getStoneColor(LevelInfo.getCurLevelMaxScore(),this.nTotalNumber)
        this.handlerNumberScale();
    }

    getShowColor():cc.Color{
        return this.node.color;
    }

    getNumber():number{
        return this.nTotalNumber;
    }

    handlerNumberScale(){

        let tempScale = 1;
        if(this.labelNumber.string.length == 1){
            tempScale = this.stoneData.scalesize01;
        }else if(this.labelNumber.string.length == 2){
            tempScale = this.stoneData.scalesize02;
        }else if(this.labelNumber.string.length == 3){
            tempScale = this.stoneData.scalesize03;
        }else if(this.labelNumber.string.length == 4){
            tempScale = this.stoneData.scalesize04;
        }
        this.labelNumber.node.setScale(tempScale)

    }

    Hit(hurt:number = 1):number{
        this.nTotalNumber = this.nTotalNumber - hurt;
        if(this.nTotalNumber <= 0){
            this.nTotalNumber = 0;
            GameManager.instance.ShakeBg(2 + this._stoneId);
            //SoundManager.palySoundById(Define.soundStonebomb)
        }
        this.labelNumber.string = Common.getShowNumber(this.nTotalNumber);
        this.handlerNumberScale();

        if(this.nTotalNumber > 0){
            this.icon.color = Common.getStoneColor(LevelInfo.getCurLevelMaxScore(),this.nTotalNumber)
            if(this.isCanShake)
            {
                this.isCanShake = false;
                let minScale = 0.9;
                if(this.stoneData.stonId > 1){
                    minScale = 0.95;
                }
                this.node.runAction(cc.sequence(cc.scaleTo(0.05,minScale),cc.scaleTo(0.05,1),
                cc.callFunc(function(){
                    this.isCanShake = true;
                }.bind(this))));
            }
        }
        return this.nTotalNumber;
    }

    onBeginContact(contact: cc.PhysicsContact, selfCollider:  cc.PhysicsCollider, otherCollider:  cc.PhysicsCollider): void{
    
        let other = otherCollider.node.name;
        if(other == "floor")
        {
            let tempPos = new cc.Vec2(this.node.position.x ,this.node.position.y - this.stoneData.radius) ;
            ParticleEffectManager.getInstance().showParticleEffect(Define.effectParticleToground,tempPos,0.5);

            this.rigidBody.linearVelocity = cc.v2(this.rigidBody.linearVelocity.x,Define.ballRestitutionMaxArr[this._stoneId]);
            GameManager.instance.ShakeBg(2 + this._stoneId);
            //SoundManager.palySoundById(Define.soundStonetoground)
        }
        else if(other.indexOf("cannon") == 0){

            if(!Common.isGod){
                if(UserInfo.curLevel <= 3){
                    UIManager.getInstance().executeEvent(Define.viewBattle,"showPrompt")
                    WXHelper.brateLong();
                }else{
                    Common.actionTinkColor(this.labelNumber.node);
                    GameManager.instance.gameOver(this);
                }
            }
        }
        if(other == "floor" ||other == "wall"){

            if(Math.abs( this.rigidBody.linearVelocity.x) > 200){
                if(this.rigidBody.linearVelocity.x > 0){
                    this.rigidBody.linearVelocity = cc.v2(100,this.rigidBody.linearVelocity.y);
                }else{
                    this.rigidBody.linearVelocity = cc.v2(-100,this.rigidBody.linearVelocity.y);
                }
            }
        }
    }

    appear(dir:number,dir1:number = -1,pos:cc.Vec2 = cc.Vec2.ZERO,intY:number = 800){ 

        this.rigidBody.active = false;
        this.rigidBody.linearVelocity = cc.Vec2.ZERO; 

        if(dir == Define.right){
            this.node.position = cc.v2(this.getAppearPosX(dir),intY);
            this.rigidBody.angularVelocity = -30
            this.node.runAction(
                cc.sequence(cc.moveTo(2,cc.v2(this.getAppearTargetX(dir),intY)),
                cc.callFunc(function(){
                    this.node.group = Define.groupBall;
                    this.rigidBody.linearVelocity = cc.v2(-100,-100);
                    this.rigidBody.active = true;
                    this.isCanDrop = true;
                }.bind(this))
            ));
        }else if(dir == Define.left){
            this.rigidBody.angularVelocity = 30
            this.node.position = cc.v2(this.getAppearPosX(dir),intY);
            this.node.runAction(
                cc.sequence(cc.moveTo(2,cc.v2(this.getAppearTargetX(dir),intY)),
                cc.callFunc(function(){
                    this.node.group = Define.groupBall;
                    this.rigidBody.linearVelocity = cc.v2(100,-100);
                    this.isCanDrop = true;;
                    this.rigidBody.active = true;
                }.bind(this))
            ));
        }
        else if(dir == Define.center){
            if(dir1 == Define.left){
                this.node.position = pos;
                this.rigidBody.angularVelocity = -30
                this.node.group = Define.groupBall;
                this.rigidBody.linearVelocity = cc.v2(-200,300);
                this.rigidBody.active = true;
                this.isCanDrop = true;
            }
            else if(dir1 == Define.right){
                this.node.position = pos;
                this.rigidBody.angularVelocity = 30
                this.node.group = Define.groupBall;
                this.rigidBody.linearVelocity = cc.v2(200,300);
                this.rigidBody.active = true;
                this.isCanDrop = true;
            }
        }
    }
    setCallBack(callBack:Function){
        this.callBack = callBack;
    }
    update (dt) {
        if(!this.isCanDrop){
            this.rigidBody.linearVelocity = cc.Vec2.ZERO;
        }

    }
    stopDrop(){
        this.rigidBody.active = false;
        this.rigidBody.linearVelocity = cc.Vec2.ZERO; 
    }

    getAppearPosX(dir:number):number{
        //移动距离大的固定的距离 240 
        if(dir == Define.left){
            return -240 + this.stoneData.radius; 
        }else if(dir == Define.right){
            return 880 - this.stoneData.radius
        }
    }

    getAppearTargetX(dir:number):number{
        if(dir == Define.left){
            return this.stoneData.radius;
        }else if(dir == Define.right){
            return  640 - this.stoneData.radius;
        }
    }

    getBreakScore():number{
        return  Math.ceil((this.initScore/2));
        /*分裂规则							
        石块上数字清零后，分裂出的数字为石块数字除以二，获得2个分数石块。						
            若出现无法被2出尽的情况，则在原分数减1，后再除以2					
        石块上为1时，只能分裂成1*/						
    }
    //是否暂停移动
    pauseMove(isPause:boolean){
        if(isPause){
            this.lastGravityScale = this.rigidBody.gravityScale
            this.lastAngularVelocity = this.rigidBody.angularVelocity
            this.lasLlinearVelocity = this.rigidBody.linearVelocity
            this.rigidBody.gravityScale = 0
            this.rigidBody.angularVelocity = 0
            this.rigidBody.linearVelocity = cc.Vec2.ZERO

            this.node.pauseAllActions();
        }else{
            this.node.resumeAllActions();
            this.rigidBody.gravityScale =  this.lastGravityScale
            this.rigidBody.angularVelocity = this.lastAngularVelocity
            this.rigidBody.linearVelocity =  this.lasLlinearVelocity
        }
    }
}
